using System;
using UnityEngine;
using EchoFramework;

/// <summary>
/// 单个DiskItem
/// </summary>
public class DiskItem : MonoBehaviour
{
    private PrefabBinder prefabBinder;
    private EchoButton starBtn;
    private EchoText starTxt;
    private EchoButton triangleBtn;
    private EchoText triangleTxt;
    private EchoButton attackBtn;
    private EchoText attackTxt;
    private EchoButton defendBtn;
    private EchoText defendTxt;
    private EchoButton magicBtn;
    private EchoText magicTxt;

    /// <summary>
    /// 星星是否为空
    /// </summary>
    private bool isStarEmpty;

    /// <summary>
    /// 星星数值
    /// </summary>
    private int starNum;

    /// <summary>
    /// 三角是否为空
    /// </summary>
    private bool isTriangleEmpty;

    /// <summary>
    /// 三角数值
    /// </summary>
    private int triangleNum;

    /// <summary>
    /// 攻击力是否为空
    /// </summary>
    private bool isAttackEmpty;

    /// <summary>
    /// 攻击力数值
    /// </summary>
    private int attackNum;

    /// <summary>
    /// 是否防御力为空
    /// </summary>
    private bool isDefenseEmpty;

    /// <summary>
    /// 防御力数值
    /// </summary>
    private int defendNum;

    /// <summary>
    /// 魔陷是否为空
    /// </summary>
    private bool isMagicEmpty;

    /// <summary>
    /// 魔陷数值
    /// </summary>
    private int magicNum;

    /// <summary>
    /// 阵营
    /// </summary>
    private CampEnum camp = CampEnum.None;

    /// <summary>
    /// 命令模块
    /// </summary>
    private CommandLogic commandLogic;

    /// <summary>
    /// 索引
    /// </summary>
    private int index;

    private void Awake()
    {
        prefabBinder = GetComponent<PrefabBinder>();
        starBtn = prefabBinder.Find("StarBtn").GetComponent<EchoButton>();
        starBtn.onClick.AddListener(OnClickStarBtn);
        starBtn.onDoubleClick.AddListener(OnDoubleClickStarBtn);
        starBtn.onLongPress.AddListener(onLongPressStarBtn);
        starTxt = prefabBinder.Find("StarTxt").GetComponent<EchoText>();
        triangleBtn = prefabBinder.Find("TriangleBtn").GetComponent<EchoButton>();
        triangleBtn.onClick.AddListener(OnClickTriangleBtn);
        triangleBtn.onDoubleClick.AddListener(OnDoubleClickTriangleBtn);
        triangleBtn.onLongPress.AddListener(onLongPressTriangleBtn);
        triangleTxt = prefabBinder.Find("TriangleTxt").GetComponent<EchoText>();
        attackBtn = prefabBinder.Find("AttackBtn").GetComponent<EchoButton>();
        attackBtn.onClick.AddListener(OnClickAttackBtn);
        attackBtn.onLongPress.AddListener(onLongPressAttackBtn);
        attackTxt = prefabBinder.Find("AttackTxt").GetComponent<EchoText>();
        defendBtn = prefabBinder.Find("DefendBtn").GetComponent<EchoButton>();
        defendBtn.onClick.AddListener(OnClickDefendBtn);
        defendBtn.onLongPress.AddListener(onLongPressDefendBtn);
        defendTxt = prefabBinder.Find("DefendTxt").GetComponent<EchoText>();
        magicBtn = prefabBinder.Find("MagicBtn").GetComponent<EchoButton>();
        magicBtn.onClick.AddListener(OnClickMagicBtn);
        magicBtn.onDoubleClick.AddListener(OnDoubleClickMagicBtn);
        magicBtn.onLongPress.AddListener(onLongPressMagicBtn);
        magicTxt = prefabBinder.Find("MagicTxt").GetComponent<EchoText>();
    }

    private void Start()
    {
        
        
        EventManager.Instance.Register(EventTypeEnum.RevocationCommandNum, RevocationCommandNum);
        EventManager.Instance.Register(EventTypeEnum.RefreshDisk, RefreshDisk);
        EventManager.Instance.Register(EventTypeEnum.Reset, ResetLogic);

    }

    
    /// <summary>
    /// 撤回时数值变化，仅变化值
    /// </summary>
    /// <param name="eventObject"></param>
    private void RevocationCommandNum(EventObject eventObject)
    {
        if (eventObject != null && eventObject.Param != null && eventObject.Param.Length >= 4)
        {
            CampEnum tempCamp = (CampEnum) eventObject.Param[0];
            DiskEnum tempDiskEnum = (DiskEnum) eventObject.Param[1];
            int retValue = (int) eventObject.Param[2];
            CommandEmptyEnum tempEmptyEnum = (CommandEmptyEnum) eventObject.Param[3];
            
            if (tempCamp == camp)
            {
                switch (tempDiskEnum)
                {
                    case DiskEnum.Star:
                        starNum = retValue;
                        isStarEmpty = tempEmptyEnum == CommandEmptyEnum.OldNumIsEmpty;
                        break;
                    case DiskEnum.Triangle:
                        triangleNum = retValue;
                        isTriangleEmpty = tempEmptyEnum == CommandEmptyEnum.OldNumIsEmpty;
                        break;
                    case DiskEnum.Attack:
                        attackNum = retValue;
                        isAttackEmpty = tempEmptyEnum == CommandEmptyEnum.OldNumIsEmpty;
                        break;
                    case DiskEnum.Defend:
                        defendNum = retValue;
                        isDefenseEmpty = tempEmptyEnum == CommandEmptyEnum.OldNumIsEmpty;
                        break;
                    case DiskEnum.Magic:
                        magicNum = retValue;
                        isMagicEmpty = tempEmptyEnum == CommandEmptyEnum.OldNumIsEmpty;
                        break;
                }
            }
        }
    }
    
    /// <summary>
    /// 计算器刷新攻击力或防御力
    /// </summary>
    private void RefreshDisk(EventObject eventObject)
    {
        if (eventObject != null && eventObject.Param != null && eventObject.Param.Length >= 4)
        {
            CampEnum tempCamp = (CampEnum) eventObject.Param[0];
            int tempIndex = (int) eventObject.Param[1];
            DiskEnum tempDiskEnum = (DiskEnum) eventObject.Param[2];
            int retValue = (int) eventObject.Param[3];
            if (tempCamp == camp && tempIndex == index)
            {
                switch (tempDiskEnum)
                {
                    case DiskEnum.Attack:
                        SafeShowNum(DiskEnum.Attack, retValue, isAttackEmpty ? CommandEmptyEnum.OldNumIsEmpty : CommandEmptyEnum.None);
                        break;
                    case DiskEnum.Defend:
                        SafeShowNum(DiskEnum.Defend, retValue, isDefenseEmpty ? CommandEmptyEnum.OldNumIsEmpty : CommandEmptyEnum.None);
                        break;
                }
            }
        }
    }
    
    /// <summary>
    /// 重置
    /// </summary>
    private void ResetLogic(EventObject eventObject)
    {
        commandLogic.Reset();
        starTxt.text = string.Empty;
        starNum = 0;
        isStarEmpty = true;
        triangleTxt.text = string.Empty;
        triangleNum = 0;
        isTriangleEmpty = true;
        attackTxt.text = string.Empty;
        attackNum = 0;
        isAttackEmpty = true;
        defendTxt.text = string.Empty;
        defendNum = 0;
        isDefenseEmpty = true;
        magicTxt.text = string.Empty;
        magicNum = 0;
        isMagicEmpty = true;
    }
    
    /// <summary>
    /// 设置数据
    /// </summary>
    /// <param name="camp">阵营</param>
    /// <param name="commandLogic">命令逻辑</param>
    /// <param name="index">索引</param>
    public void SetData(CampEnum camp, CommandLogic commandLogic, int index)
    {
        this.camp = camp;
        this.commandLogic = commandLogic;
        this.index = index;
        ResetLogic(null);
    }

    /// <summary>
    /// 安全显示文本内容
    /// </summary>
    /// <param name="diskEnum">盘面枚举</param>
    /// <param name="num">要显示的数值</param>
    /// <param name="emptyEnum">是否为空</param>
    private void SafeShowNum(DiskEnum diskEnum, int num, CommandEmptyEnum emptyEnum)
    {
        num = num < 0 ? 0 : num;
        switch (diskEnum)
        {
            case DiskEnum.Star:
                if (starNum == num && isStarEmpty == (emptyEnum == CommandEmptyEnum.NewNumIsEmpty))
                    return;
                
                isStarEmpty = emptyEnum == CommandEmptyEnum.NewNumIsEmpty;
                int oldStarNum = starNum;
                starNum = num;
                commandLogic.ExecutiveCommand(new TextCommand(starTxt, oldStarNum, starNum, camp, diskEnum, emptyEnum));
                break;
            case DiskEnum.Triangle:
                if (triangleNum == num && isTriangleEmpty == (emptyEnum == CommandEmptyEnum.NewNumIsEmpty))
                    return;
                
                isTriangleEmpty = emptyEnum == CommandEmptyEnum.NewNumIsEmpty;
                int oldTriangleNum = triangleNum;
                triangleNum = num;
                commandLogic.ExecutiveCommand(new TextCommand(triangleTxt, oldTriangleNum, triangleNum, camp, diskEnum,
                    emptyEnum));
                break;
            case DiskEnum.Attack:
                if (attackNum == num && isAttackEmpty == (emptyEnum == CommandEmptyEnum.NewNumIsEmpty))
                    return;
                
                isAttackEmpty = emptyEnum == CommandEmptyEnum.NewNumIsEmpty;
                int oldAttackNum = attackNum;
                attackNum = num;
                commandLogic.ExecutiveCommand(new TextCommand(attackTxt, oldAttackNum, attackNum, camp, diskEnum,
                    emptyEnum));
                break;
            case DiskEnum.Defend:
                if (defendNum == num && isDefenseEmpty == (emptyEnum == CommandEmptyEnum.NewNumIsEmpty))
                    return;
                
                isDefenseEmpty = emptyEnum == CommandEmptyEnum.NewNumIsEmpty;
                int oldDefendNum = defendNum;
                defendNum = num;
                commandLogic.ExecutiveCommand(new TextCommand(defendTxt, oldDefendNum, defendNum, camp, diskEnum,
                    emptyEnum));
                break;
            case DiskEnum.Magic:
                if (magicNum == num && isMagicEmpty == (emptyEnum == CommandEmptyEnum.NewNumIsEmpty))
                    return;
                
                isMagicEmpty = emptyEnum == CommandEmptyEnum.NewNumIsEmpty;
                int oldMagicNum = magicNum;
                magicNum = num;
                commandLogic.ExecutiveCommand(new TextCommand(magicTxt, oldMagicNum, magicNum, camp, diskEnum, emptyEnum));
                break;
        }
    }

    private void OnClickStarBtn()
    {
        SafeShowNum(DiskEnum.Star, starNum + 1, isStarEmpty ? CommandEmptyEnum.OldNumIsEmpty : CommandEmptyEnum.None);
    }

    private void OnDoubleClickStarBtn()
    {
        SafeShowNum(DiskEnum.Star, starNum - 1, CommandEmptyEnum.None);
    }

    private void onLongPressStarBtn()
    {
        SafeShowNum(DiskEnum.Star, 0, CommandEmptyEnum.NewNumIsEmpty);
    }

    private void OnClickTriangleBtn()
    {
        SafeShowNum(DiskEnum.Triangle, triangleNum + 1, isTriangleEmpty ? CommandEmptyEnum.OldNumIsEmpty : CommandEmptyEnum.None);
    }

    private void OnDoubleClickTriangleBtn()
    {
        SafeShowNum(DiskEnum.Triangle, triangleNum - 1, CommandEmptyEnum.None);
    }

    private void onLongPressTriangleBtn()
    {
        SafeShowNum(DiskEnum.Triangle, 0, CommandEmptyEnum.NewNumIsEmpty);
    }

    private void OnClickAttackBtn()
    {
        UIViewManager.Instance.OpenWindow(UIViewID.CalculatorView, camp, index, DiskEnum.Attack, attackNum);
    }

    private void onLongPressAttackBtn()
    {
        SafeShowNum(DiskEnum.Attack, 0, CommandEmptyEnum.NewNumIsEmpty);
    }

    private void OnClickDefendBtn()
    {
        UIViewManager.Instance.OpenWindow(UIViewID.CalculatorView, camp, index, DiskEnum.Defend, defendNum);
    }

    private void onLongPressDefendBtn()
    {
        SafeShowNum(DiskEnum.Defend, 0, CommandEmptyEnum.NewNumIsEmpty);
    }

    private void OnClickMagicBtn()
    {
        SafeShowNum(DiskEnum.Magic, magicNum + 1,  isMagicEmpty ? CommandEmptyEnum.OldNumIsEmpty : CommandEmptyEnum.None);
    }

    private void OnDoubleClickMagicBtn()
    {
        SafeShowNum(DiskEnum.Magic, magicNum - 1, CommandEmptyEnum.None);
    }

    private void onLongPressMagicBtn()
    {
        SafeShowNum(DiskEnum.Magic, 0, CommandEmptyEnum.NewNumIsEmpty);
    }

    private void OnDestroy()
    {
        EventManager.Instance.UnRegister(EventTypeEnum.RevocationCommandNum, RevocationCommandNum);
        EventManager.Instance.UnRegister(EventTypeEnum.RefreshDisk, RefreshDisk);
        EventManager.Instance.Register(EventTypeEnum.Reset, ResetLogic);
    }
}